home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 323_01 / explod.c < prev    next >
Text File  |  1990-08-04  |  31KB  |  965 lines

  1. /****************************************************************************
  2. * EXPLOD.C - simple fireworks for Hercules/CGA/EGA
  3. *
  4. * This program was developed with Datalight C 2.20 and Arrowsoft ASM 1.00d.
  5. * (It also works with Turbo C 1.5/MASM 5.0 with one EQU change in EXPA.ASM).
  6. * The code should be compilable by most other C compilers. However, the
  7. * segment names in EXPA.ASM will have to be changed to suit the compiler.
  8. *
  9. * To compile:
  10. *       asm expa ;            OR        masm /mx expa ;
  11. *       dlc explod.c expa.obj            (don't forget the /mx !!!)
  12. *                        tcc explod.c expa.obj
  13. * (C) 1989 Dennis Lo
  14. * You are free to use and distribute this source code, provided that the
  15. * authors' names remain in the code, and that both the source and executables 
  16. * of modified versions are clearly distinguished from the originals with
  17. * descriptive messages.
  18. *
  19. * Change Log
  20. * 89/06/24 Dennis Lo         V1.0 Initial release.
  21. * 89/07/03 Dennis Lo         V1.1 Added cmd line options.  Code cleanups.
  22. * 89/07/26 Erik Liljencrantz Added EGA support with autodetection
  23. *                            Restores previous CRT textmode on exit
  24. * 89/08/19 Dennis Lo         V1.2 Code cleanups.  Changed references to frames
  25. *                 table to use segment and offsets so that multiple
  26. *                 frames tables can be supported in the future 
  27. *                 without switching to a large data memory model.
  28. * 89/09/03 Erik Liljencrantz Added VGA support with autodetection
  29. * 90/01/20 Dennis Lo         V2.0 Allow multiple explosion frame tables.
  30. *                 Read in explosion shape tables from data files.
  31. *                 Added -f and keypress options.  Split part of
  32. *                 functionality into expgen.c.  Keyboard control.
  33. *                 -n option.
  34. ****************************************************************************/
  35.  
  36. #include <stdio.h>
  37. #include <ctype.h>
  38. #ifndef DLC
  39. #   include <dir.h>
  40. #endif
  41. #include <dos.h>
  42. #include "explod.h"
  43.  
  44. #define PUT(s) fputs(s,stdout)
  45.  
  46. /*=====================================================================
  47.  * External assembler routines.  
  48.  *=====================================================================
  49.  */
  50. /* Datalight C does not prepend underscores to external names */
  51. #ifdef DLC
  52. #   define DosAlloc    _DosAlloc
  53. #   define DosFree    _DosFree
  54. #   define DosMemLeft    _DosMemLeft
  55. #   define ChkKey    _ChkKey
  56. #   define gr_card    _gr_card
  57. #   define gr_setcard    _gr_setcard
  58. #   define gr_gmode    _gr_gmode
  59. #   define gr_tmode    _gr_tmode
  60. #   define gr_addr    _gr_addr
  61. #   define gr_store_pt    _gr_store_pt
  62. #   define gr_frplot    _gr_frplot
  63. #endif
  64.  
  65. extern unsigned short DosAlloc();
  66. extern unsigned short DosFree();
  67. extern unsigned short DosMemLeft();
  68. extern int ChkKey();
  69. extern int gr_card();
  70. extern gr_setcard();
  71. extern gr_gmode();
  72. extern gr_tmode();
  73. extern int gr_addr();
  74. extern gr_store_pt();
  75. extern gr_frplot();
  76. #define DEADPOINT 32767    /* this must match the definition in expa.asm */
  77.  
  78. /*=====================================================================
  79.  * Configuration Parameters
  80.  *=====================================================================
  81.  */
  82. /* Video parameters */
  83. static int Interlace_factor;
  84. static int Screen_xsize;
  85. static int Screen_ysize;
  86.  
  87. /* Animation parameters */
  88. static int Simul_exps = -1;      /* # of simultaneous explosions */
  89. static int Delay_factor = 0;    /* amount to delay after each frame */
  90.  
  91. /* Explosion parameters */
  92. static int Gravity = 0;        /* Gravity override */
  93. static int Wind = 0;        /* Wind override */
  94. static int Centre_x;        /* Coords of centre of screen */
  95. static int Centre_y;
  96. static unsigned int Centre_y_mask;
  97.  
  98. /* Explosion control parameters */
  99. static int Leave_trail = 0;    /* If non-0 then don't erase explosions */
  100. static int Event_limit = 0;    /* # of exp events before exiting */
  101. static int Total_frames = 0;    /* used to find avg #frames per explosion */
  102.  
  103. /*=====================================================================
  104.  * Explosion Creation table:
  105.  * Temporarily keeps track of the parameters and points of an explosion
  106.  * while its frames are being calculated.
  107.  *=====================================================================
  108.  */
  109. /* 16.16 fixed point type: overlays a 32-bit long with its 16-bit
  110.    whole number part and its 16-bit fractional part */
  111. typedef union         
  112. {
  113.     long l;
  114.     struct             /* Note: this is endian dependent */
  115.     {
  116.         unsigned short ls;
  117.         short ms;
  118.     } s;
  119. } fixed; 
  120.  
  121. /* Structure of an explosion point at explosion creation */
  122. typedef struct 
  123. {
  124.     fixed x, y;                 /* location */
  125.     fixed xv, yv;               /* velocity */
  126.     fixed xa, ya;               /* acceleration */
  127.     int alive;                  /* liveness: 0=dead */
  128. } exp_pt_type;
  129.  
  130. /* Explosion creation table */
  131. exp_pt_type Pt_table [MAX_POINTS+1];
  132.  
  133. /*=====================================================================
  134.  * Explosion type descriptor - contains all information in a ready-to-
  135.  * playback explosion, including a pointer to its frames table.  The
  136.  * frames table contains an array of MAX_FRAMES frames.  Each frame is
  137.  * one frame in the animation of the explosion, and consists of 
  138.  * MAX_POINTS structures of the form {offset (2 bytes), value (1 byte)}.
  139.  * The frame table structure treated only as a block of memory by the
  140.  * C code, so it is not explicitly declared. (It cannot be declared
  141.  * in C in a portable way due to structure alignment padding.)
  142.  *=====================================================================
  143.  */
  144. #define FRAME_PT_SIZE 3        /* size of one point in the frame table */
  145. #define MAX_EXP_DESC    30    /* Max # of explosion types */
  146.  
  147. /* Explosion descriptor type */
  148. typedef struct
  149. {
  150.     int nframes;
  151.     int npoints;
  152.     int xsize;
  153.     int ysize;
  154.     int gravity;
  155.     int wind;
  156.     int trail_len;
  157.     unsigned short frame_seg;
  158.     unsigned short frame_ofs;
  159. } exp_desc_type;
  160.  
  161. /* Array of explosion descriptors for the explosions read in from disk */
  162. static exp_desc_type    Exp_desc [MAX_EXP_DESC];/* Explosion descriptors */
  163. static int        Num_exp_desc;        /* # of explosions read in */
  164.  
  165.  
  166. /*=====================================================================
  167.  * Explosion Event Table - each entry controls one instance of an 
  168.  * active explosion event during playback.
  169.  *=====================================================================
  170.  */
  171. #define MAX_EXPS 48     /* max # of simultaneously active explosion events */
  172.  
  173. /* Explosion events table */
  174. typedef struct 
  175. {
  176.     int centre;             /* addr of centre of explosion */
  177.     int frame_num;          /* frame #. Dead if -1 */
  178.     exp_desc_type *exp_desc;    /* explosion type */
  179. } exp_event_type;
  180. static exp_event_type Exp_ev_tab [MAX_EXPS]; 
  181.  
  182.  
  183.  
  184. /*====================================================================
  185.  * Return a random number between 0..maxval
  186.  *====================================================================
  187.  */
  188. int
  189. rnd (maxval)
  190. int maxval;
  191. {
  192. #   define MAX_RAND 32767       /* max val returned by rand() */
  193.     long l;
  194.  
  195.     l = (long) maxval * rand() / MAX_RAND;
  196.     return ((int) l);
  197. }
  198.  
  199. /*====================================================================
  200.  * Read a number from a string - replaces the need for sscanf() which
  201.  * reduces the size of the executable by about 2.5K.
  202.  * Returns a ptr to the next word in the string.
  203.  *====================================================================
  204.  */
  205. char *
  206. str_to_num (str, num)
  207. char *str;    /* IN: ptr to string containing the number */
  208. int *num;    /* OUT: the number read */
  209. {
  210.     /* Skip leading spaces */
  211.     while (*str  &&  *str == ' ') str++;
  212.  
  213.     *num = atoi (str);
  214.  
  215.     /* Skip non spaces (skip past the number) */
  216.     while (*str  &&  *str != ' ') str++;
  217.  
  218.     return (str);
  219. }
  220.  
  221. /*====================================================================
  222.  * Local memory allocator:
  223.  * MemInit() - allocates as much memory from DOS as possible.
  224.  *           Return 1 if successful, 0 if not.
  225.  * MemAlloc() - allocates a block of memory to the caller.
  226.  *        Returns segment addr of block, or 0 if failed.
  227.  * MemCleanup() - returns all memory